﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using LFSRecord2.Model.Replay;
using LFSRecord2.View.Dialogs;
using LFSRecord2.Misc;

namespace LFSRecord2.View.TimelineStructures
{
    /// <summary>
    /// Interaction logic for SelectionGridItem.xaml
    /// </summary>
    public partial class TimeSelectionGridItem : UserControl
    {
        public bool IsSelectable = true; 
        private bool _isSelected = false;
        public bool IsSelected 
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                HandleIsSelected();
            }
        }

        public static readonly DependencyProperty StartTimeProperty = DependencyProperty.Register(
            "StartTime",
            typeof(double),
            typeof(TimeSelectionGridItem),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnStartTimeChanged))
        );
        public double StartTime
        {
            get { return (double)GetValue(StartTimeProperty); }
            set { SetValue(StartTimeProperty, value); }
        }
        private static void OnStartTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TimeSelectionGridItem)d).setIndicatorPositions();
        }

        public static readonly DependencyProperty EndTimeProperty = DependencyProperty.Register(
            "EndTime",
            typeof(double),
            typeof(TimeSelectionGridItem),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnEndTimeChanged))
        );
        public double EndTime
        {
            get { return (double)GetValue(EndTimeProperty); }
            set { SetValue(EndTimeProperty, value); }
        }
        private static void OnEndTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TimeSelectionGridItem)d).setIndicatorPositions();
        }

        public double SuggestedStartTime { get; set; }
        public double SuggestedEndTime { get; set; }
        public double TotalTime { get; set; }

        public TimeSelectionGridItem()
        {
            SuggestedStartTime = -1;
            SuggestedEndTime = -1;
            InitializeComponent();
        }

        private void HandleIsSelected()
        {
            if (_isSelected)
            {
                StartIndicator.Visibility = Visibility.Visible;
                EndIndicator.Visibility = Visibility.Visible;
                HeaderRect.Fill = new SolidColorBrush(Colors.CornflowerBlue);
            }
            else
            {
                StartIndicator.Visibility = Visibility.Hidden;
                EndIndicator.Visibility = Visibility.Hidden;
                HeaderRect.Fill = new SolidColorBrush(Colors.DarkGray);
            }
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            HandleIsSelected();
            //Debug.WriteLine("GridItem width : " + ActualWidth);

            setIndicatorPositions();

            if (SuggestedStartTime > -1 && SuggestedEndTime > -1 && TotalTime > 0)
            {
                ProjectTimeRectangle.Visibility = Visibility.Visible;
                ProjectTimeRectangle.Width = (SuggestedEndTime / TotalTime * (this.ActualWidth - 3)) - (SuggestedStartTime / TotalTime * (this.ActualWidth - 3));
                ProjectTimeRectangle.Margin = new Thickness(SuggestedStartTime / TotalTime * (this.ActualWidth - 3), 0, 0, 0);
            }
            else
            {
                ProjectTimeRectangle.Visibility = Visibility.Hidden;
            }

            StartTimeLabel.Text = TimeHelper.Seconds2TimeStamp(0);
            EndTimeLabel.Text = TimeHelper.Seconds2TimeStamp(TotalTime);
        }

        void setIndicatorPositions()
        {
            if (!IsInitialized || this.ActualWidth == 0 || TotalTime == 0)
                return;

            StartIndicator.Margin = new Thickness(StartTime / TotalTime * (this.ActualWidth - 3), 0, 0, 0);
            EndIndicator.Margin = new Thickness(0, 0, (1 - EndTime / TotalTime) * (this.ActualWidth - 3), 0);
        }

        private void SelectionGridItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!IsSelectable || IsSelected)
                return;
        }

        Point _startPoint;
        double _origMargin;
        private void StartIndicator_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            _startPoint = e.GetPosition(this);
            _origMargin = StartIndicator.Margin.Left;

            Application.Current.MainWindow.CaptureMouse();
            Application.Current.MainWindow.MouseMove += StartIndicator_MouseMove;
            Application.Current.MainWindow.MouseUp += StartIndicator_MouseUp;
        }

        private void StartIndicator_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Application.Current.MainWindow.ReleaseMouseCapture();
            Application.Current.MainWindow.MouseMove -= StartIndicator_MouseMove;
            Application.Current.MainWindow.MouseUp -= StartIndicator_MouseUp;
        }

        private void StartIndicator_MouseMove(object sender, MouseEventArgs e)
        {
            Point curPoint = e.GetPosition(this);
            double leftMargin = _origMargin + (curPoint.X - _startPoint.X);
            if (leftMargin < 0)
                leftMargin = 0;
            else if (leftMargin > this.ActualWidth - 3)
                leftMargin = this.ActualWidth - 3;
            StartIndicator.Margin = new Thickness(leftMargin, 0, 0, 0);

            // Max EndIndicator rightMargin
            double rightMargin = this.ActualWidth - EndIndicator.Margin.Right;
            if (leftMargin + 3 > rightMargin)
                EndIndicator.Margin = new Thickness(0, 0, this.ActualWidth - leftMargin - 3, 0);

            StartTime = (leftMargin / (this.ActualWidth - 3)) * TotalTime;
        }

        private void EndIndicator_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            _startPoint = e.GetPosition(this);
            _origMargin = EndIndicator.Margin.Right;

            Application.Current.MainWindow.CaptureMouse();
            Application.Current.MainWindow.MouseMove += EndIndicator_MouseMove;
            Application.Current.MainWindow.MouseUp += EndIndicator_MouseUp;
        }

        private void EndIndicator_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Application.Current.MainWindow.ReleaseMouseCapture();
            Application.Current.MainWindow.MouseMove -= EndIndicator_MouseMove;
            Application.Current.MainWindow.MouseUp -= EndIndicator_MouseUp;
        }

        private void EndIndicator_MouseMove(object sender, MouseEventArgs e)
        {
            Point curPoint = e.GetPosition(this);
            double rightMargin = _origMargin - (curPoint.X - _startPoint.X);
            if (rightMargin < 0)
                rightMargin = 0;
            else if (rightMargin > this.ActualWidth - 3)
                rightMargin = this.ActualWidth - 3;
            EndIndicator.Margin = new Thickness(0, 0, rightMargin, 0);

            // Max StartIndicator rightMargin
            double leftMargin = this.ActualWidth - StartIndicator.Margin.Left;
            if (rightMargin + 3 > leftMargin)
                StartIndicator.Margin = new Thickness(this.ActualWidth - rightMargin - 3, 0, 0, 0);

            EndTime = (1 - (rightMargin / (this.ActualWidth - 3))) * TotalTime;
        }
    }
}
